package com.intelligent.eayon.handler;

import com.intelligent.eayon.dto.RequestDto;
import com.intelligent.eayon.message.MessageHead;
import com.intelligent.eayon.message.TransMessage;
import com.intelligent.eayon.utils.AppConstant;
import com.intelligent.eayon.utils.ByteUtils;
import com.intelligent.eayon.utils.MessageUtils;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AdapterHandler extends ChannelInboundHandlerAdapter {

    private static Logger logger = LoggerFactory.getLogger(AdapterHandler.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        RequestDto requestDto = (RequestDto) msg;

        ChannelPipeline p = ctx.pipeline();
        clearPipeline(p);

        if (AppConstant.REQ_SIGN == requestDto.getCode()) {
            p.addLast("SignUpHandler", new SignUpHandler());
        } else if (AppConstant.REQ_SR == requestDto.getCode()) {
            p.addLast("InteractionHandler", new InteractionHandler());
        } else if (AppConstant.REQ_SM == requestDto.getCode()){
            p.addLast("SendMessageHandler", new SendMessageHandler());
        } else {
            MessageHead messageHead = new MessageHead();

            byte[] error = ByteUtils.intToBytes(ExceptionMessages.ERR_18001);
            byte[] errc = new byte[6];
            for (int i = 2; i < 6; i++) {
                errc[i] = error[i - 2];
            }
            messageHead.setErrc(errc);

            TransMessage message = MessageUtils.buildTransMessage(messageHead, null);

            ctx.writeAndFlush(message);
            logger.error("The protocol code is not supported.");
        }

        ctx.fireChannelRead(requestDto);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {

        MessageHead messageHead = new MessageHead();

        byte[] error;
        if (cause instanceof ApplicationException) {
            error = ByteUtils.intToBytes(((ApplicationException) cause).getCode());
        } else {
            error = ByteUtils.intToBytes(ExceptionMessages.ERR_20001);
        }
        byte[] errc = new byte[6];
        for (int i = 2; i < 6; i++) {
            errc[i] = error[i - 2];
        }
        messageHead.setErrc(errc);

        TransMessage message = MessageUtils.buildTransMessage(messageHead, null);
        ctx.writeAndFlush(message);
        logger.error("exceptionCaught from AdapterHandler: " + cause);
        cause.printStackTrace();

    }

    private void clearPipeline(ChannelPipeline p) {
        if (p.get("SignUpHandler") != null) {
            p.remove("SignUpHandler");
        }
        if (p.get("InteractionHandler") != null) {
            p.remove("InteractionHandler");
        }
        if (p.get("SendMessageHandler") != null) {
            p.remove("SendMessageHandler");
        }
    }
}
